package com.ybb.production.service.impl;

import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ybb.production.domain.GarmentProductionBianfei;
import com.ybb.production.domain.GarmentProductionCuttingBedInfo;
import com.ybb.production.domain.GarmentProductionOrder;
import com.ybb.production.domain.GarmentProductionUpnumberRecord;
import com.ybb.production.dto.GarmentProductionPayDetailParam;
import com.ybb.production.dto.GarmentProductionPrintDTO;
import com.ybb.production.mapper.GarmentProductionBianfeiMapper;
import com.ybb.production.mapper.GarmentProductionCuttingBedInfoMapper;
import com.ybb.production.mapper.GarmentProductionOrderMapper;
import com.ybb.production.responce.GarmentBianfeiCompleteDetailResp;
import com.ybb.production.responce.GarmentPayDetailResp;
import com.ybb.production.responce.GarmentPrintTicketResp;
import com.ybb.production.service.IGarmentProductionBianfeiService;
import com.yubb.common.constant.CacheConstants;
import com.yubb.common.core.domain.saas.vo.SysUserVO;
import com.yubb.common.core.redis.RedisCache;
import com.yubb.common.utils.DateUtils;
import com.yubb.common.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 编菲信息Service业务层处理
 *
 * @author dengjie
 * @date 2023-09-09
 */
@Service
public class GarmentProductionBianfeiServiceImpl implements IGarmentProductionBianfeiService {
    @Autowired
    private GarmentProductionBianfeiMapper garmentProductionBianfeiMapper;

    @Autowired
    private GarmentProductionProcessServiceImpl garmentProductionProcessService;

    @Autowired
    private GarmentProductionOrderMapper garmentProductionOrderMapper;

    @Autowired
    private GarmentProductionCuttingBedInfoMapper garmentProductionCuttingBedInfoMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询编菲信息
     *
     * @param id 编菲信息主键
     * @return 编菲信息
     */
    @Override
    public GarmentProductionBianfei selectGarmentProductionBianfeiById(Long id) {
        return garmentProductionBianfeiMapper.selectGarmentProductionBianfeiById(id);
    }

    /**
     * 查询编菲信息列表
     *
     * @param garmentProductionBianfei 编菲信息
     * @return 编菲信息
     */
    @Override
    public List<GarmentProductionBianfei> selectGarmentProductionBianfeiList(GarmentProductionBianfei garmentProductionBianfei) {
        return garmentProductionBianfeiMapper.selectGarmentProductionBianfeiList(garmentProductionBianfei);
    }

    /**
     * 新增编菲信息
     *
     * @param garmentProductionBianfei 编菲信息
     * @return 结果
     */
    @Override
    public int insertGarmentProductionBianfei(GarmentProductionBianfei garmentProductionBianfei) {
        return garmentProductionBianfeiMapper.insertGarmentProductionBianfei(garmentProductionBianfei);
    }

    /**
     * 修改编菲信息
     *
     * @param garmentProductionBianfei 编菲信息
     * @return 结果
     */
    @Override
    public int updateGarmentProductionBianfei(GarmentProductionBianfei garmentProductionBianfei) {
        garmentProductionBianfei.setUpdateTime(DateUtils.getNowDate());
        return garmentProductionBianfeiMapper.updateGarmentProductionBianfei(garmentProductionBianfei);
    }

    /**
     * 批量删除编菲信息
     *
     * @param ids 需要删除的编菲信息主键
     * @return 结果
     */
    @Override
    public int deleteGarmentProductionBianfeiByIds(Long[] ids) {
        return garmentProductionBianfeiMapper.deleteGarmentProductionBianfeiByIds(ids);
    }

    /**
     * 删除编菲信息信息
     *
     * @param id 编菲信息主键
     * @return 结果
     */
    @Override
    public int deleteGarmentProductionBianfeiById(Long id) {
        return garmentProductionBianfeiMapper.deleteGarmentProductionBianfeiById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int editUpNum(List<GarmentProductionBianfei> bianfeiParam) {
        for (GarmentProductionBianfei bianfei : bianfeiParam) {
            bianfei.setStatus(1L);
            bianfei.setUpTime(DateUtils.getNowDate());
            garmentProductionBianfeiMapper.updateGarmentProductionBianfei(bianfei);
        }
        return 1;
    }

    @Override
    public int editUpNumCancel(String ids) {
        SysUserVO loginUser = ShiroUtils.getSysUser();

        List<GarmentProductionBianfei> existsList = garmentProductionBianfeiMapper.selectListByIds(ids);
        for (GarmentProductionBianfei bianfei : existsList) {
            if (!(Long.parseLong(loginUser.getId()) == bianfei.getUpId())) {
                return 0;
            }
        }
        return garmentProductionBianfeiMapper.editUpNumCancel(ids);
    }

    @Override
    public Integer qryUpNums(GarmentProductionBianfei bianfei) {
        return garmentProductionBianfeiMapper.qryRemainingUpNums(bianfei);
    }

    @Override
    public String qryPrintSetting() {
        Object cacheObject = redisCache.getCacheObject(CacheConstants.PRINT_TICKET_SETTING);
        return cacheObject == null ? null : cacheObject.toString();
    }

    @Override
    public int addPrintSetting(JSONObject printSetting) {
        redisCache.setCacheObject(CacheConstants.PRINT_TICKET_SETTING, printSetting.toJSONString());
        return 1;
    }

    @Override
    public List<GarmentBianfeiCompleteDetailResp> qryBianfeiByBundleNo(Long cuttingBedId) {
        List<GarmentBianfeiCompleteDetailResp> bianfeis = garmentProductionProcessService.selectListByBundleNo(cuttingBedId);
        return bianfeis;
    }

    @Override
    public List<GarmentPrintTicketResp> printTicket(GarmentProductionPrintDTO dto) {
        List<GarmentPrintTicketResp> garmentPrintTicketResps = new ArrayList<>();
        List<GarmentProductionBianfei> bianfeis = garmentProductionBianfeiMapper.selectListByIds(dto.getBianfeiIds().stream()
                .map(String::valueOf)
                .collect(Collectors.joining(",")));

        GarmentProductionOrder order = garmentProductionOrderMapper.selectGarmentProductionOrderById(bianfeis.get(0).getOrderId());
        GarmentProductionCuttingBedInfo bedInfo = garmentProductionCuttingBedInfoMapper.selectGarmentProductionCuttingBedInfoById(bianfeis.get(0).getCuttindbedId());
        // 查询部位
        String portion = dto.getPortion();

        for (GarmentProductionBianfei bianfei : bianfeis) {
            GarmentPrintTicketResp ticketResp = new GarmentPrintTicketResp();
            ticketResp.setBianfeiId(bianfei.getId());
            ticketResp.setCuttingBedId(bianfei.getCuttindbedId());
            ticketResp.setBedNo(bedInfo.getbedNo());
            ticketResp.setBundleNo(String.valueOf(bianfei.getBundleNo()));
            ticketResp.setBoltNo(bianfei.getBoltNo());
            ticketResp.setColor(bianfei.getColor());
            ticketResp.setSize(bianfei.getSize());
            ticketResp.setRemark(bianfei.getRemark());
            ticketResp.setStyleCode(order.getStyleCode());
            ticketResp.setPrintTime(DateUtils.getNowDate());
            ticketResp.setEnterprise("服装工厂");
            ticketResp.setQuantity(bianfei.getQuantity());
            ticketResp.setPortion(portion);
            String qrCode = "cuttintbedId=" + bianfei.getCuttindbedId() + "&" + "bianfeiId=" + bianfei.getId();

            BufferedImage image = QrCodeUtil.generate(qrCode, 200, 200);
            //输出流
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            try {
                ImageIO.write(image, "png", stream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            String qrCodeBase64 = Base64.getEncoder().encodeToString(stream.toByteArray());

            ticketResp.setQrCode("data:image/png;base64," + qrCodeBase64);
            garmentPrintTicketResps.add(ticketResp);
        }


        return garmentPrintTicketResps;
    }

    public void deleteGarmentProductionBianfeiByCuttingBedIds(Long[] cuttingBedIds) {
        garmentProductionBianfeiMapper.deleteGarmentProductionBianfeiByCuttingBedIds(cuttingBedIds);
    }

    public List<Map<String, Object>> selectGarmentProductionBianfeiListByCuttingId(Set<Long> cuttingIds) {
        return garmentProductionBianfeiMapper.selectGarmentProductionBianfeiListByCuttingId(cuttingIds);
    }

    public List<GarmentProductionBianfei> selectGarmentProductionBianfeiListByBundleNos(List<GarmentProductionUpnumberRecord> bundleNos) {
        return garmentProductionBianfeiMapper.selectGarmentProductionBianfeiListByBundleNos(bundleNos);
    }

    public void batchInsert(List<GarmentProductionBianfei> insertList) {
        garmentProductionBianfeiMapper.batchInsert(insertList);
    }

    public List<Long> selectGarmentProductionBianfeiListByProcessIds(List<Long> lastProcessIds) {
        return garmentProductionBianfeiMapper.selectGarmentProductionBianfeiListByProcessIds(lastProcessIds);
    }

    public List<GarmentProductionBianfei> qryBianFeiSum(List<Long> cuttingIds, List<Long> processId) {
        return garmentProductionBianfeiMapper.qryBianFeiSum(cuttingIds, processId);
    }

    public List<Map<String, Object>> qryCompleteProcessCnt(Set<Long> cuttingIds) {
        return garmentProductionBianfeiMapper.qryCompleteProcessCnt(cuttingIds);
    }

    public int qryAllCuttingBedCnt() {
        return garmentProductionBianfeiMapper.qryAllCuttingBedCnt();
    }

    public List<Map<String, String>> qryCntSalaryByUserIds(JSONObject param) {
        return garmentProductionBianfeiMapper.qryCntSalaryByUserIds(param);
    }

    public List<GarmentPayDetailResp> qryPayDetail(GarmentProductionPayDetailParam detailParam) {
        return garmentProductionBianfeiMapper.qryPayDetail(detailParam);
    }

    public List<GarmentProductionBianfei> selectListByIds(List<Long> ids) {
        return garmentProductionBianfeiMapper.selectListByIds(ids.stream().map(String::valueOf).collect(Collectors.joining(",")));
    }

    public void updatePayStatus(JSONObject param) {
        garmentProductionBianfeiMapper.updatePayStatus(param);
    }
}
